package com.lzb.service;

import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

import com.lzb.common.constant.CommonConstantValues;
import com.lzb.common.constant.favourite.ConstantValues;
import com.lzb.common.helper.redis.RedisHelper;

@Service(FavouriteService.BEAN_PACKAGE_NAME)
public class FavouriteService {

	private static final Logger logger = LoggerFactory.getLogger(FavouriteService.class);
	public static final String BEAN_PACKAGE_NAME = "com.lzb.service.FavouriteService";
	
	@Autowired
	private RedisHelper redisHelper;
	
	/*
	 * 
	a.用户-朋友圈映射:
		数据结构:zset
		key = `user-moment-mapping:` + userUUID
		value = [momentUUID...]
		score = createDate + createTime
	b.朋友圈-点赞用户id映射:
		数据结构:zset(可实现时间倒序)
		key = `moment-favourite-user-mapping:` + momentUUID
		value = [userUUID...]
		score = currentDateTime
	c.session缓存:
		数据结构:hash
		key = sessionId or userUUID ? 
		value = currentLoginedUser
	d.结果集缓存:
		数据结构:string
		key = 包名.类名.方法名.[参数]
		value = json序列化的结果集
	e.主页只显示最新的20条朋友圈:
		数据结构:list
		key = theNewestTwentyMoment
		value = [momentUUID...]
	 * 
	 * */
	/**
	 * 用户点赞的朋友圈
	 * */
	public void doAddUserFavourite(String userUUID, String momentUUID, double score) {
		String key = ConstantValues.MOMENT_FAVOURITE_USER_MAPPING + CommonConstantValues.REDIS_SPLITTER + momentUUID;
		String value = userUUID;
		Set<String> existeduserUUIDs = doGetFavouritesByScoreDesc(key, 0, -1);
		//防止用户重发点赞
		if(!existeduserUUIDs.contains(userUUID)) {
			redisHelper.zadd(key, score, value);
		}
	}
	
	/**
	 * 用户发表朋友圈
	 * */
	public void doAddUserMoment(String userUUID, String momentUUID, double score) {
		String key = ConstantValues.USER_MOMENT_MAPPING + CommonConstantValues.REDIS_SPLITTER + userUUID;
		String value = momentUUID;
		Jedis jedis = null;
		Pipeline pipe = null;
		try {
			jedis = redisHelper.getJedis();
			pipe = jedis.pipelined();
			pipe.zadd(key, score, value);
			//只存储最新的20条朋友圈
			pipe.lpush(ConstantValues.THE_NEWEST_MOMENT_KEY, value);
			pipe.ltrim(ConstantValues.THE_NEWEST_MOMENT_KEY, 0, ConstantValues.THE_NEWEST_MOMENT_SIZE - 1);
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			redisHelper.closePipeline(pipe);
			redisHelper.returnResource();
		}
	}
	
	/**
	 * 用户删除朋友圈
	 * */
	public void doDeleteMoment(String userUUID, String momentUUID) {
		/*
		 * 可采用“管道”串行执行命令
		 * 1.删除用户对应的朋友圈
		 * 2.删除关联的点赞信息
		 * 3.删除展示首页的朋友圈
		 * */
		Jedis jedis = null;
		Pipeline pipe = null;
		try {
			jedis = redisHelper.getJedis();
			pipe = jedis.pipelined();
			pipe.multi();
			String key0 = ConstantValues.USER_MOMENT_MAPPING + CommonConstantValues.REDIS_SPLITTER + userUUID;
			pipe.zrem(key0, momentUUID);
			String key1 = ConstantValues.MOMENT_FAVOURITE_USER_MAPPING + CommonConstantValues.REDIS_SPLITTER + momentUUID;
			pipe.del(key1);
			pipe.lrem(ConstantValues.THE_NEWEST_MOMENT_KEY, 0, momentUUID);
			pipe.exec();
		} catch(Exception e) {
			logger.error("朋友圈删除出错", e);
		} finally {
			redisHelper.closePipeline(pipe);
			redisHelper.returnResource();
		}
	}
	
	/**
	 * 按时间倒序获取朋友圈的“点赞”
	 * @param momentUUID
	 * @param start 起始位置，0开始
	 * @param end 结束位置，可以为负
	 * @return 用户UUIDs
	 */
	public Set<String> doGetFavouritesByScoreDesc(String momentUUID, int start, int end) {
		return redisHelper.zrevrange(ConstantValues.MOMENT_FAVOURITE_USER_MAPPING + CommonConstantValues.REDIS_SPLITTER + momentUUID, start, end);
	}
	
	/**
	 * 获取用户所有的朋友圈
	 * */
	public Set<String> doGetUserMomentsByRange(String userUUID, int startIndex, int endIndex) {
		return redisHelper.zrevrange(ConstantValues.USER_MOMENT_MAPPING + CommonConstantValues.REDIS_SPLITTER + userUUID, startIndex, endIndex);
	}
	
	/**
	 * 获取用户发布朋友圈的总数
	 * */
	public long doGetUserMomentsCount(String userUUID) {
		return redisHelper.zcard(ConstantValues.USER_MOMENT_MAPPING + CommonConstantValues.REDIS_SPLITTER + userUUID);
	}
	
	/**
	 * 获取所有朋友圈中最新的20条
	 * */
	public List<String> doGetTheNewestMoment() {
		return redisHelper.lrange(ConstantValues.THE_NEWEST_MOMENT_KEY, 0, ConstantValues.THE_NEWEST_MOMENT_SIZE - 1);
	}
}
